package solutions.ferpa.ztest.rest.action;

import br.com.telescope.adsrt.lib.BaseRuntime;
import br.com.telescope.adsrt.lib.RecordNotFoundException;
import br.com.telescope.auth.AdsrtSession;
import br.com.telescope.auth.AdsrtUser;
import br.com.telescope.t2.config.Config;
import org.apache.commons.lang.math.NumberUtils;
import solutions.ferpa.ztest.ent.EntPessoa;
import solutions.ferpa.ztest.ent.EntUsuarios;
import solutions.ferpa.ztest.rest.RestService;
import solutions.ferpa.ztest.rest.model.res.AuthLogonRQ;
import solutions.ferpa.ztest.rest.model.res.AuthLogonRS;
import solutions.ferpa.ztest.rest.model.User;

import java.util.Date;
@RestAction(action = "logon", rqType = AuthLogonRQ.class, rsType = AuthLogonRS.class, restricted = false)
public class AuthLogon extends RestService<AuthLogonRQ, AuthLogonRS> {

    public AuthLogon(BaseRuntime ctx) {
        super(ctx);
    }

    @Override
    public AuthLogonRS call() throws Exception {
        AuthLogonRQ request = bindRequest(AuthLogonRQ.class);
        AdsrtSession session = (AdsrtSession) ctx.getSession();
        Config cfg = Config.getInstance();
        AuthLogonRS response = new AuthLogonRS();
        String userName = request.getLogin().toLowerCase();
        String senha = request.getEncryptedPassword();

        if (userName == null || userName.isEmpty()) {
            //TODO: tratar traduções;
            response.getAlerts().addError("O login do usuário dever ser informado.");
        }

        if (senha == null || senha.isEmpty()) {
            //TODO: tratar traduções;
            response.getAlerts().addError("A senha dever ser informada.");
        }

        if (!response.getAlerts().hasErrors()) {
            session.setObject("MENU", null); // Limpa o menu do cache
            try {
                EntUsuarios user = null;
                EntPessoa pessoa = null;

                if (NumberUtils.isDigits(userName.substring(0, 3))) {
                    pessoa = new EntPessoa(ctx);
                    try {
                        user = pessoa.joinUsuarioAssociado();
                        pessoa.findByCodigo(userName);
                    } catch (RecordNotFoundException e) {
                        user = new EntUsuarios(ctx);
                        user.findByLogin(userName);
                    }
                } else {
                    user = new EntUsuarios(ctx);
                    user.findByLogin(userName);
                }

                if (senha.equals(user.valueOfSenhaHash())) {
                    if (user.valueOfAtivo().equals("S")) {
                        AdsrtUser auser = new AdsrtUser();
                        auser.setDisplayName(user.valueOfNomeCompleto());
                        auser.setEmail(user.valueOfEMail());
                        auser.setId(String.valueOf(user.valueOfId()));
                        auser.setLoginName(user.valueOfLogin());
                        auser.setSuperUser(user.valueOfSuperUsuario().equals("S"));
                        auser.setPersonId(user.valueOfPessoaId());
                        session.login(auser);
                        // Se tiver data de validade
                        if (user.getValidade().isNotNull()) {
                            // E ela for inferior a data de hoje
                            if (user.valueOfValidade().compareTo(new Date()) <= 0) {
                                //TODO: Tratar tradução de mensagens;
                                response.getAlerts().addError("Sua senha expirou.");
                            }
                        } else {
                            User login = new User();
                            login.setId(user.valueOfId());
                            login.setLogin(user.valueOfLogin());
                            login.setName(user.valueOfNomeCompleto());

                            if (pessoa == null) {
                                pessoa = new EntPessoa(ctx);
                                try {
                                    pessoa.findByUsuarioAssociado(user);
                                } catch (Exception e) {
                                    login.setPersonId(null);
                                }
                            } else  {
                                login.setPersonId(pessoa.valueOfId());
                            }

                            response.setResource(login);
                        }
                    } else {
                        response.getAlerts().addError(message("RTAUTH.INACTIVE_USER", "Usuário inativo."));
                    }
                } else {
                    response.getAlerts().addError(message("RTAUTH.USER_NOT_FOUND", "Usuário e/ou senha estão incorretos."));
                }
            } catch (RecordNotFoundException ex) {
                response.getAlerts().addError(message("RTAUTH.USER_NOT_FOUND", "Usuário e/ou senha estão incorretos."));
            } catch (Exception ex) {
                //TODO: Tratar tradução de mensagens;
                response.getAlerts().addError("Não foi possível autenticar no sistema.");
            }
        }

        String tz = request.getTimeZone();
        if (tz != null && !tz.isEmpty()) {
            ctx.setTimeZone(tz);
            ctx.setSessionString("TIME_ZONE", tz);
        }

        return response;
    }

}
